package org.grayrabbit.cms.util;

import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.grayrabbit.cms.constant.EmailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class EmailUtil {
	
	private static final Logger LOG = LoggerFactory.getLogger(EmailUtil.class);
	
	/**用户名*/
	private String emailUser = EmailService.EMAIL_LOGINNAME;
	/**密码*/
	private String passwd = EmailService.EMAIL_PASSWORD;
	/**发送人*/
	private String fromMailAddress = emailUser;
	/**邮件服务器*/
	private String server = EmailService.EMAIL_SERVER;
	/**端口*/
	private int port = Integer.parseInt(EmailService.EMAIL_PORT);
	/**是否调试*/
	private boolean sessionDebug = false;
	/**email传输格式*/
	private String format = EmailService.EMAIL_FORMAT;
	
	private MimeMessage msg;
	/**邮件传输*/
	private Transport transport;
	/**配置信息类*/
	private Properties prop = new Properties();
	
	/**
	 * email参数初始化
	 * @throws MessagingException 
	 */
	private void init() throws MessagingException{
		prop.put("mail.smtp.host", server);
		prop.put("mail.smtp.port", String.valueOf(port));
		prop.put("mail.smtp.auth", "true");
		Session session = Session.getDefaultInstance(prop, null);
		transport = session.getTransport("smtp");
		session.setDebug(sessionDebug);
		transport.connect(server, emailUser, passwd);
		msg = new MimeMessage(session);
	}
	
	public EmailUtil(){
		
	}
	
	public EmailUtil(String server, String passwd, String user){
		this.server = server;
		this.passwd = passwd;
		this.emailUser = user;
	}
	
	/**
	 * 发送文本格式的Email
	 * 
	 * @param toMailAddress
	 *            收件人地址
	 * @param subject
	 *            标题
	 * @param body
	 *            内容
	 * @return
	 */
	public boolean sendTextEmail(String toMailAddress, String subject, String body, Date sendDate){
		return sendTextEmail(new String[]{toMailAddress}, subject, body, sendDate);
	}

	public boolean sendTextEmail(String[] toMailAddress, String subject, String body, Date sendDate) {
		try {
			init();
			Address fromAddress = new InternetAddress(fromMailAddress);
			Address[] toAddress = new InternetAddress[toMailAddress.length];
			for(int i = 0; i < toMailAddress.length; i++){
				toAddress[i] = new InternetAddress(toMailAddress[i]);
			}
			if(sendDate == null){
				msg.setSentDate(new Date());
			}else{
				msg.setSentDate(sendDate);
			}
			msg.setFrom(fromAddress);
			msg.setRecipients(Message.RecipientType.TO, toAddress);
			msg.setSubject(subject, format);
			msg.setText(body, format);
			msg.saveChanges();
			return commit();
		} catch (Exception e) {
			LOG.error("发送异常:", e);
			return false;
		}
	}
	
	/**
	 * 发送Html类型的Email
	 * 
	 * @param toMailAddress
	 *            收件人地址
	 * @param subject
	 *            标题
	 * @param body
	 *            内容
	 * @return
	 */
	public boolean sendHtmlEmail(String toMailAddress, String subject, String body, Date sendDate){
		return sendHtmlEmail(new String[]{toMailAddress}, subject, body, sendDate);
	}

	public boolean sendHtmlEmail(String[] toMailAddress, String subject, String body, Date sendDate) {
		try{
			init();
			Address fromAddress = new InternetAddress(fromMailAddress);
			Address[] toAddress = new InternetAddress[toMailAddress.length];
			for(int i = 0; i < toMailAddress.length; i++){
				toAddress[i] = new InternetAddress(toMailAddress[i]);
			}
			// 使用MimeMultipart和MimeBodyPart才能发HTML格式邮件。
			BodyPart bodyPart = new MimeBodyPart();
			bodyPart.setContent(body, "text/html;charset=" + format);
			Multipart mp = new MimeMultipart();
			mp.addBodyPart(bodyPart);
			msg.setSubject(subject);
			msg.setContent(mp);
			if(sendDate == null){
				msg.setSentDate(new Date());
			}else{
				msg.setSentDate(sendDate);
			}
			msg.setFrom(fromAddress);
			msg.setRecipients(Message.RecipientType.TO, toAddress);
			msg.saveChanges();
			return commit();
		}catch(Exception e){
			LOG.error("发送异常:", e);
			return false;
		}
	}
	
	/**
	 * 带有附件的Email,内容为HTML
	 * 
	 * @param toMailAddress
	 * @param subject
	 * @param body
	 * @param filename
	 * @return
	 */
	public boolean sendAccessoryEmail(String toMailAddress, String subject, String body, String filename, Date sendDate){
		return sendAddressoryEmail(new String[]{toMailAddress}, subject, body, new String[]{filename}, sendDate);
	}

	public boolean sendAddressoryEmail(String[] toMailAddress, String subject,
			String body, String[] filename, Date sendDate) {
		try{
			init();
			Address fromAddress = new InternetAddress(fromMailAddress);
			Address[] toAddress = new InternetAddress[toMailAddress.length];
			for(int i = 0; i < toMailAddress.length; i++){
				toAddress[i] = new InternetAddress(toMailAddress[i]);
			}
			Multipart mp = new MimeMultipart();
			BodyPart bodypart = new MimeBodyPart();
			bodypart.setContent(body, "text/html;charset="+format);
			mp.addBodyPart(bodypart);
			for(int i = 0; i < filename.length; i++){
				bodypart = new MimeBodyPart();
				FileDataSource fds = new FileDataSource(filename[i]);
				DataHandler dh = new DataHandler(fds);
				bodypart.setFileName(MimeUtility.encodeText(fds.getFile().getName()));
				bodypart.setDataHandler(dh);
				mp.addBodyPart(bodypart);
			}
			msg.setSubject(subject);
			msg.setContent(mp);
			if(sendDate == null){
				msg.setSentDate(new Date());
			}else{
				msg.setSentDate(sendDate);
			}
			msg.setFrom(fromAddress);
			msg.setRecipients(Message.RecipientType.TO, toAddress);
			msg.saveChanges();
			return commit();
		}catch(Exception e){
			LOG.error("发送异常:", e);
			return false;
		}
	}

	private boolean commit() {
		try {
			transport.sendMessage(msg, msg.getAllRecipients());
			transport.close();
			return true;
		} catch (Exception e) {
			LOG.error("发送异常:", e);
			return false;
		}
	}

}
